package com.blue.excel.util;

import com.blue.excel.annotation.*;
import com.blue.excel.model.ColumnField;
import com.blue.excel.model.OverrideTitle;
import com.blue.excel.type.Alignment;
import com.blue.excel.type.CellType;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;

import java.lang.reflect.Field;
import java.util.*;

/**
 * Created by ChenYaHui on 2017/8/1.
 */
public class ExcelTransformer extends ExcelTransformerBase {


    public void prepareSheet(Class clasz,List<OverrideTitle> overrideTitles, List<String> resortFieldNames){
        columnFields.clear();
        stackRow = titleRow = remarkRow = null;
        hasStackRow = hasRemarkRow = false;
        bgColorField = null;


        currentRowIndex = 0;
        if(bigTitle != null){
            hasBigTitle = true;
        }
        if(!hasBigTitle && currentSheetInfo != null && !"".equals(currentSheetInfo.head())){
            hasBigTitle = true;
            bigTitle = currentSheetInfo.head();
        }
        if(hasBigTitle){
            currentRowIndex ++;
        }

        //遍历一遍，普通标注的字段、做为扩展字段的对象的字段、做为合并单元格的对象或map都被整理到columnFields
        Field[] fields = clasz.getFields();
        Set<String> fieldNames = new HashSet<>();
        for(Field field : fields){
            ColumnField columnField = new ColumnField();
            columnField.field = field;
            //普通标注
            if(field.isAnnotationPresent(ColField.class)){
                ColField colField = field.getAnnotation(ColField.class);
                columnField.registerInter(colField.valueInterceptorId());
                columnField.colField = colField;
                columnField.title = colField.title();
                if(!"".equals(colField.stack().value())){
                    hasStackRow = true;
                }
                if(!"".equals(colField.remark())){
                    hasRemarkRow = true;
                }


                columnFields.add(columnField);
                fieldNames.add(field.getName());
            }
            //扩展标注
            else if(field.isAnnotationPresent(ExtendCols.class)){
                ExtendCols extendCols = field.getAnnotation(ExtendCols.class);
                columnField.extendCols = extendCols;
                columnField.title = extendCols.title();
                if(!"".equals(columnField.title)){
                    hasStackRow = true;
                }

                if(extendCols.itemClass() == Object.class){
                    if(!field.getType().isAssignableFrom(Map.class)){
                        Field[] innerFields = field.getType().getFields();
                        for(Field innerField : innerFields){
                            if(innerField.isAnnotationPresent(ColField.class)){
                                ColField colField = innerField.getAnnotation(ColField.class);
                                if(!"".equals(colField.stack().value())){
                                    hasStackRow = true;
                                }
                                if(!"".equals(colField.remark())){
                                    hasRemarkRow = true;
                                }
                                columnField.columnFields.add(new ColumnField(innerField,colField));
                            }
                        }
                    }else{
                        columnField.isMap = true;
                        columnField.registerInter(extendCols.valueInterceptorId());
                    }

                    columnFields.add(columnField);
                    fieldNames.add(field.getName());
                }else{
                    Field[] innerFields = extendCols.itemClass().getFields();
                    boolean tempHasRemarkRow = hasRemarkRow;
                    for(Field innerField : innerFields){
                        if(innerField.isAnnotationPresent(ColField.class)){
                            ColField colField = innerField.getAnnotation(ColField.class);
                            if(!"".equals(colField.remark())){
                                hasRemarkRow = true;
                            }
                            columnField.columnFields.add(new ColumnField(innerField,colField));
                        }
                        if(innerField.isAnnotationPresent(KeyField.class)){
                            columnField.keyField = innerField;
                        }
                    }
                    if(columnField.keyField != null){
                        hasStackRow = true;
                        columnFields.add(columnField);
                        fieldNames.add(field.getName());
                    }else{
                        hasRemarkRow = tempHasRemarkRow;
                    }
                }
            }
            else if(field.isAnnotationPresent(SplitCols.class)){
                SplitCols splitCols = field.getAnnotation(SplitCols.class);
                columnField.splitCols = splitCols;
                columnField.title = splitCols.title();
                if(!"".equals(columnField.title)){
                    hasStackRow = true;
                }
                if(splitCols.itemClass() == Object.class){
                    if(!field.getType().isAssignableFrom(Map.class)){
                        fillChildrenColumnFields(columnField,field.getType());
                    }else{
                        columnField.isMap = true;
                        columnField.registerInter(splitCols.valueInterceptorId());
                    }
                }
                else{
                    fillChildrenColumnFields(columnField,splitCols.itemClass());
                }

                columnFields.add(columnField);
                fieldNames.add(field.getName());
            }
            else if(field.isAnnotationPresent(BgColor.class)){
                bgColorField = field;
            }

        }




        //用overrideTitles复写标题
        if (overrideTitles != null && overrideTitles.size() > 0) {
            for(OverrideTitle overrideTitle : overrideTitles){
                String[] title = overrideTitle.fieldName.split("\\.");
                for(ColumnField columnField : columnFields){
                    if(title.length == 1 && columnField.field.getName().equals(title[0])){
                        columnField.title = overrideTitle.title;
                    }
                    else if(title.length == 2 && columnField.field.getName().equals(title[0])){
                        if(columnField.columnFields != null && !columnField.columnFields.isEmpty()){
                            for(ColumnField innerColumnField : columnField.columnFields){
                                if(innerColumnField.field.getName().equals(title[1])){
                                    innerColumnField.title = overrideTitle.title;
                                }
                            }
                        }
                    }

                }
            }
        }



        //用resortfieldNames冲洗排列字段顺序
        if (resortFieldNames != null && resortFieldNames.size() > 0) {
            for( int i = resortFieldNames.size() - 1; i >= 0; i--){
                if(!fieldNames.contains(resortFieldNames.get(i))){
                    resortFieldNames.remove(i);
                }
            }

            for(int i = 0; i < resortFieldNames.size(); i++){
                for(ColumnField columnField : columnFields){
                    if(columnField.field.getName().equals(resortFieldNames.get(i))){
                        ColumnField temp = columnField;
                        columnFields.remove(columnField);
                        columnFields.add(i,temp);
                        break;
                    }

                }
            }
        }

        //把stackTo的列放到stack列后面
        for(int i = 0; i < columnFields.size(); i++){
            ColumnField columnField = columnFields.get(i);
            if(columnField.colField != null){
                if(columnField.colField.stack().stackTo().length != 0){
                    String[] stackToFields = columnField.colField.stack().stackTo();
                    int stackToIndex = 0;
                    for(String stackToField : stackToFields){
                        for(int j = 0; j < columnFields.size(); j ++){
                            ColumnField currentLook = columnFields.get(j);
                            if(currentLook.field.getName().equals(stackToField)){
                                ColumnField temp = currentLook;
                                columnFields.remove(currentLook);
                                if(j < i){
                                    columnFields.add(i + stackToIndex,temp);
                                }else{
                                    columnFields.add(i + 1 + stackToIndex,temp);
                                }
                                break;
                            }

                        }
                        stackToIndex ++;
                    }
                }

            }
            else if(columnField.extendCols != null){
                if(!columnField.isMap){
                    for(int j = 0; j < columnField.columnFields.size(); j++){
                        ColumnField innerColumnField = columnField.columnFields.get(j);
                        if(innerColumnField.colField.stack().stackTo().length != 0){
                            String[] innerStackToFields = innerColumnField.colField.stack().stackTo();
                            int stackToIndex = 0;
                            for(String innerStackToField : innerStackToFields){
                                for(int k = 0;k < columnField.columnFields.size(); k++){
                                    ColumnField currentLook = columnField.columnFields.get(k);
                                    if(currentLook.field.getName().equals(innerStackToField)){
                                        ColumnField temp = currentLook;
                                        columnField.columnFields.remove(currentLook);
                                        if(k < j){
                                            columnField.columnFields.add(j + stackToIndex,temp);
                                        }else{
                                            columnField.columnFields.add(j + 1 + stackToIndex,temp);
                                        }
                                        break;
                                    }
                                }
                                stackToIndex ++;
                            }

                        }
                    }
                }
            }
        }


        //大标题行
        if(hasStackRow){
            stackRow = currentSheet.createRow(currentRowIndex);
            for(int i = 0; i < columnFields.size(); i++){
                ColumnField columnField = columnFields.get(i);
                int currentIndexBase = getNextColumnIndex(i);
                if(columnField.colField != null){
                    Cell stackCell = stackRow.createCell(currentIndexBase);
                    stackCell.setCellType(Cell.CELL_TYPE_STRING);
                    stackCell.setCellStyle(stackStyle);
                    if(columnField.colField.stack().stackTo().length != 0){
                        stackCell.setCellValue(columnField.colField.stack().value());
                        excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum(),currentIndexBase,currentIndexBase + columnField.colField.stack().stackTo().length);
                    }
                }
                else if(columnField.splitCols != null){
                    if(!"".equals(columnField.title) && columnField.getSpan() > 0){
                        Cell stackCell = excelHelper.getOrCreateCell(stackRow,currentIndexBase);
                        stackCell.setCellType(Cell.CELL_TYPE_STRING);
                        stackCell.setCellStyle(stackStyle);
                        stackCell.setCellValue(columnField.title);
                        excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum(),currentIndexBase,currentIndexBase + columnField.getSpan() - 1);
                    }
                }
                else if(columnField.extendCols != null){
                    ExtendCols extendCols = columnField.extendCols;
                    if(extendCols.itemClass() == Object.class){
                        if(!columnField.isMap){
                            if(!"".equals(columnField.title) && columnField.getSpan() > 0){
                                Cell stackCell = excelHelper.getOrCreateCell(stackRow, currentIndexBase);
                                stackCell.setCellStyle(stackStyle);
                                stackCell.setCellValue(columnField.title);
                                excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum(),currentIndexBase,currentIndexBase + columnField.getSpan() - 1);
                            }
                            else{
                                for(int j = 0; j < columnField.columnFields.size(); j++){
                                    Cell stackCell = stackRow.createCell(currentIndexBase + j);
                                    stackCell.setCellType(Cell.CELL_TYPE_STRING);
                                    stackCell.setCellStyle(stackStyle);
                                    if(columnField.columnFields.get(j).colField.stack().stackTo().length != 0){
                                        stackCell.setCellValue(columnField.columnFields.get(j).colField.stack().value());
                                        excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum(),currentIndexBase + j,currentIndexBase + j + columnField.columnFields.get(j).colField.stack().stackTo().length);
                                    }
                                }
                            }
                        }
                    }

                }
            }

            currentRowIndex ++;
        }

        //标题行
        titleRow = currentSheet.createRow(currentRowIndex);
        for(int i = 0; i < columnFields.size(); i++){
            int currentIndexBase = getNextColumnIndex(i);
            ColumnField columnField = columnFields.get(i);
            if(columnField.colField != null){
                ColField colField = columnField.colField;
                Cell titleCell = setTitleCellValue(currentIndexBase,columnField.title);

                if(hasStackRow && !excelHelper.isInMergeRegion(stackRow.getRowNum(), currentIndexBase)){
                    stackRow.getCell(currentIndexBase).setCellValue(titleCell.getStringCellValue());
                    titleCell.setCellValue("");
                    excelHelper.mergeRegion(stackRow.getRowNum(),titleRow.getRowNum(),currentIndexBase,currentIndexBase);
                }
                //存储宽度
                if(colField.width() != -1){
                    columnsWidth.put(currentIndexBase,colField.width());
                }
                else{
                    dealColumnWidth(titleCell);
                }
            }else if(columnField.splitCols != null){
                SplitCols splitCols = columnField.splitCols;
                if(splitCols.itemClass() == Object.class){
                    Cell keyTitleCell = setTitleCellValue(currentIndexBase, splitCols.keyTitle());
                    dealColumnWidth(keyTitleCell);
                    dealColumnWidth(setTitleCellValue(currentIndexBase + 1, splitCols.valueTitle()));

                }else{
                    for(int j = 0; j < columnField.columnFields.size(); j++){
                        ColumnField innerColumnField = columnField.columnFields.get(j);
                        dealColumnWidth(setTitleCellValue(currentIndexBase + j, innerColumnField.title));
                    }
                }
                if(hasStackRow && "".equals(splitCols.title())){
                    for(int j = 0; j < columnField.getSpan(); j++){
                        Cell sourceCell = excelHelper.getOrCreateCell(titleRow,currentIndexBase + j);
                        Cell targetCell = excelHelper.getOrCreateCell(stackRow,currentIndexBase + j);
                        targetCell.setCellStyle(stackStyle);
                        excelHelper.copyCellValue(targetCell,sourceCell,false);
                        excelHelper.mergeRegion(stackRow.getRowNum(), titleRow.getRowNum(),currentIndexBase + j,currentIndexBase + j);
                    }
                }

            }else if(columnField.extendCols != null){
                ExtendCols extendCols = columnField.extendCols;
                if(extendCols.itemClass() == Object.class){
                    if(!columnField.isMap){
                        for(int j = 0; j < columnField.columnFields.size(); j++) {
                            ColumnField innerColumnField = columnField.columnFields.get(j);
                            Cell currentTitleCell = setTitleCellValue(currentIndexBase + j,innerColumnField.title);
                            if(hasStackRow && !excelHelper.isInMergeRegion(stackRow.getRowNum(),currentIndexBase + j)){
                                stackRow.getCell(currentIndexBase + j).setCellValue(currentTitleCell.getStringCellValue());
                                currentTitleCell.setCellValue("");
                                excelHelper.mergeRegion(stackRow.getRowNum(),titleRow.getRowNum(),currentIndexBase + j,currentIndexBase + j);
                            }
                            //存储宽度
                            if(innerColumnField.colField.width() != -1){
                                columnsWidth.put(currentIndexBase + j, innerColumnField.colField.width());
                            }
                            else{
                                dealColumnWidth(currentTitleCell);
                            }
                        }
                    }
                }

            }


        }
        currentRowIndex ++;
        //标题 end

        //总标题
        if(hasBigTitle){
            Row firstRow = excelHelper.getOrCreateRow(0);
            Cell firstCell = excelHelper.getOrCreateCell(firstRow,0);

            excelHelper.fillCell(firstCell,bigTitle, Alignment.Auto);
            excelHelper.setBigTitle(firstCell);
            excelHelper.mergeRegion(0,0,0,getMaxDataCols() - 1);
        }


        //备注行
        if(hasRemarkRow){
            remarkRow = currentSheet.createRow(currentRowIndex);
            for(int i = 0; i < columnFields.size(); i++) {
                int currentIndexBase = getNextColumnIndex(i);
                ColumnField columnField = columnFields.get(i);
                if(columnField.colField != null){
                    Cell remarkCell = remarkRow.createCell(currentIndexBase);
                    remarkCell.setCellType(Cell.CELL_TYPE_STRING);
                    remarkCell.setCellStyle(remarkStyle);
                    if(!"".equals(columnField.colField.remark())){
                        remarkCell.setCellValue(columnField.colField.remark());
                    }
                }
                else if(columnField.extendCols != null){
                    ExtendCols extendCols = columnField.extendCols;
                    if(extendCols.itemClass() == Object.class){
                        if(!columnField.isMap){
                            for(int j = 0; j < columnField.columnFields.size(); j++) {
                                ColumnField innerColumnField = columnField.columnFields.get(j);
                                Cell currentRemarkCell = remarkRow.createCell(currentIndexBase + j);
                                currentRemarkCell.setCellType(Cell.CELL_TYPE_STRING);
                                currentRemarkCell.setCellStyle(remarkStyle);
                                if(!"".equals(innerColumnField.colField.remark())){
                                    currentRemarkCell.setCellValue(innerColumnField.colField.remark());
                                }
                            }
                        }
                    }

                }

            }
            currentRowIndex ++;
        }


    }


    public int entityToRow(Object entity,Set<Integer> deeperBgColorRegions,Set<Integer> notMergeCols) throws IllegalAccessException {
        Row currentRow = currentSheet.createRow(currentRowIndex);
        int mergeRowMaxNum = 0;

        for(int i = 0; i < columnFields.size(); i++){
            int currentIndexBase = getNextColumnIndex(i);
            ColumnField columnField = columnFields.get(i);
            Object fieldValue = columnField.field.get(entity);
            if(fieldValue == null){
                continue;
            }
            if(columnField.colField != null){
                Cell currentCell = currentRow.createCell(currentIndexBase);
//                Object fieldValue = columnField.field.get(entity);
                excelHelper.fillCell(currentCell, fieldValue,columnField.colField.alignment(),columnField);
                if(columnField.colField.width() == -1){
                    dealColumnWidth(currentCell,currentIndexBase);
                }
            }
            else if(columnField.splitCols != null){
                SplitCols splitCols = columnField.splitCols;
//                Object fieldValue = columnField.field.get(entity);
                for(int innerIndex = 0; innerIndex < columnField.getSpan(); innerIndex ++){
                    notMergeCols.add(currentIndexBase + innerIndex);
                }
                int mergeRowNum = 0;
                if(splitCols.itemClass() == Object.class){
                    if(columnField.isMap){
                        Map mapValue = (Map) fieldValue;
                        for(Object obj : mapValue.keySet()){
                            Row row = excelHelper.getOrCreateRow(currentRowIndex + mergeRowNum);
                            Cell keyCell = excelHelper.getOrCreateCell(row,currentIndexBase);
                            excelHelper.fillCell(keyCell,obj,Alignment.Auto);
                            dealColumnWidth(keyCell);
                            Cell valueCell = excelHelper.getOrCreateCell(row,currentIndexBase + 1);
                            excelHelper.fillCell(valueCell,mapValue.get(obj),Alignment.Auto,columnField);
                            dealColumnWidth(valueCell);
                            mergeRowNum ++;
                        }
                    }else{
                        for(int j = 0; j < columnField.columnFields.size(); j++) {
                            ColumnField innerColumnField = columnField.columnFields.get(j);
                            Row row = excelHelper.getOrCreateRow(currentRowIndex + mergeRowNum);
                            Cell keyCell = excelHelper.getOrCreateCell(row,currentIndexBase);
                            excelHelper.fillCell(keyCell,innerColumnField.colField.title(),Alignment.Auto);
                            dealColumnWidth(keyCell);
                            Cell valueCell = excelHelper.getOrCreateCell(row,currentIndexBase + 1);
                            excelHelper.fillCell(valueCell,innerColumnField.field.get(fieldValue),innerColumnField.colField.alignment(),innerColumnField);
                            dealColumnWidth(valueCell);
                            mergeRowNum ++;
                        }
                    }
                }else{
                    Collection collection = (Collection) fieldValue;
                    Iterator iterator = collection.iterator();
                    while (iterator.hasNext()){
                        Row row = excelHelper.getOrCreateRow(currentRowIndex + mergeRowNum);
                        Object obj = iterator.next();
                        for(int j = 0; j < columnField.columnFields.size(); j++) {
                            ColumnField innerColumnField = columnField.columnFields.get(j);
                            Cell currentCell = excelHelper.getOrCreateCell(row,currentIndexBase + j);
                            excelHelper.fillCell(currentCell,innerColumnField.field.get(obj),innerColumnField.colField.alignment(),innerColumnField);
                            if(innerColumnField.colField.width() == -1){
                                dealColumnWidth(currentCell,currentIndexBase + j);
                            }
                        }
                        mergeRowNum ++;
                    }

                }

                if(mergeRowNum > mergeRowMaxNum){
                    mergeRowMaxNum = mergeRowNum;
                }
            }
            else if(columnField.extendCols != null){
//                Object fieldValue = columnField.field.get(entity);
                ExtendCols extendCols = columnField.extendCols;
                if(extendCols.itemClass() == Object.class){
                    if(columnField.isMap){
                        Map<String,Object> mapFieldValue = (Map<String, Object>) fieldValue;
                        for(Object obj : mapFieldValue.keySet()){
                            int innerIndex = columnField.getMapKeyIndex(String.valueOf(obj));
                            Cell currentCell = null;
                            if(innerIndex != -1){
                                currentCell = excelHelper.getOrCreateCell(currentRow,currentIndexBase + innerIndex);
                            }else{
                                int nowIndex = currentIndexBase + columnField.mapKeys.size();
                                excelHelper.pushColumnsRightFrom(nowIndex,1);
                                //更新不需要合并单元格的列索引set
                                Set<Integer> newNotMergeCols = new HashSet<>();
                                for(Integer index : notMergeCols){
                                    if(index >= nowIndex){
                                        newNotMergeCols.add(index + 1);
                                    }
                                    else{
                                        newNotMergeCols.add(index);
                                    }
                                }
                                notMergeCols.clear();
                                notMergeCols.addAll(newNotMergeCols);
                                //end

                                //更新列宽index和宽度的Map
                                Map<Integer,Integer> newColumnsWidth = new HashMap<>();
                                for(Integer index : columnsWidth.keySet()){
                                    if(index >= nowIndex){
                                        newColumnsWidth.put(index + 1,columnsWidth.get(index));
                                    }else{
                                        newColumnsWidth.put(index,columnsWidth.get(index));
                                    }
                                }
                                columnsWidth = newColumnsWidth;

                                Cell currentTitleCell = setTitleCellValue(nowIndex,String.valueOf(obj));
                                dealColumnWidth(currentTitleCell);
                                currentCell = excelHelper.getOrCreateCell(currentRow,nowIndex);
                                //合并大小标题备注区的单元格
                                if(!"".equals(columnField.title)){
                                    if(columnField.mapKeys.size() > 0){
                                        int mergeRegionIndex = excelHelper.getMergeRegion(stackRow.getRowNum(), stackRow.getRowNum(), currentIndexBase, currentIndexBase + columnField.mapKeys.size() - 1);
                                        if(mergeRegionIndex != -1){
                                            currentSheet.removeMergedRegion(mergeRegionIndex);
                                        }
                                    }
                                    Cell stackCell = excelHelper.getOrCreateCell(stackRow, currentIndexBase);
                                    stackCell.setCellStyle(stackStyle);
                                    excelHelper.getOrCreateCell(stackRow, currentIndexBase).setCellValue(columnField.title);
                                    excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum(),currentIndexBase,currentIndexBase + columnField.mapKeys.size());
                                }else{
                                    if(hasStackRow){
                                        Cell stackCell = excelHelper.getOrCreateCell(stackRow, currentTitleCell.getColumnIndex());
                                        stackCell.setCellStyle(stackStyle);
                                        excelHelper.copyCellValue(stackCell,currentTitleCell,false);
                                        excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum() + 1,nowIndex,nowIndex);
                                    }
                                }

                                columnField.mapKeys.add(String.valueOf(obj));
                            }
                            Object value = mapFieldValue.get(obj);
                            excelHelper.fillCell(currentCell,value,Alignment.Auto,columnField);
                            dealColumnWidth(currentCell);
                        }

                    }else{
                        for(int j = 0; j < columnField.columnFields.size(); j++){
                            ColumnField innerColumnField = columnField.columnFields.get(j);
                            Cell currentCell = currentRow.createCell(currentIndexBase + j);
                            Object value = innerColumnField.field.get(fieldValue);
                            excelHelper.fillCell(currentCell,value,innerColumnField.colField.alignment(),innerColumnField);
                            if(innerColumnField.colField.width() == -1){
                                dealColumnWidth(currentCell,currentIndexBase + j);
                            }
                        }
                    }
                }else{
                    Collection collection = (Collection) fieldValue;
                    Iterator iterator = collection.iterator();
                    while (iterator.hasNext()){
                        Object obj = iterator.next();
                        String mapKey = String.valueOf(columnField.keyField.get(obj));
                        int innerIndex = columnField.getMapKeyIndex(mapKey);
//                        Cell currentCell = null;
                        if(innerIndex != -1){
                            int currentInnerBase = currentIndexBase + innerIndex * columnField.columnFields.size();
                            for(int j = 0; j < columnField.columnFields.size(); j++) {
                                ColumnField innerColumnField = columnField.columnFields.get(j);
                                Cell currentCell = excelHelper.getOrCreateCell(currentRow,currentInnerBase + j);
                                excelHelper.fillCell(currentCell,innerColumnField.field.get(obj),innerColumnField.colField.alignment(),innerColumnField);
                                if(innerColumnField.colField.width() == -1){
                                    dealColumnWidth(currentCell);
                                }
                            }
                        }
                        else{
                            int nowIndex = currentIndexBase + columnField.getSpan();
                            int step = columnField.columnFields.size();
                            excelHelper.pushColumnsRightFrom(nowIndex,step);
                            addSetIndex(notMergeCols,nowIndex,step);

                            columnsWidth = addMapIndex(columnsWidth,nowIndex,step);

                            Cell stackCell = excelHelper.getOrCreateCell(stackRow,nowIndex);
                            excelHelper.fillCell(stackCell,mapKey,Alignment.Center);
                            excelHelper.mergeRegion(stackRow.getRowNum(),stackRow.getRowNum(),nowIndex,nowIndex + columnField.columnFields.size() - 1);

                            for(int j = 0; j < columnField.columnFields.size(); j++) {
                                ColumnField innerColumnField = columnField.columnFields.get(j);

                                Cell currentTitleCell = setTitleCellValue(nowIndex + j,innerColumnField.colField.title());
                                dealColumnWidth(currentTitleCell);
                                if(!"".equals(innerColumnField.colField.remark())){
                                    Cell currentRemartCell = excelHelper.getOrCreateCell(remarkRow,nowIndex + j);
                                    excelHelper.fillCell(currentRemartCell,innerColumnField.colField.remark(),Alignment.Center);
                                }


                                Cell currentCell = excelHelper.getOrCreateCell(currentRow,nowIndex + j);
                                excelHelper.fillCell(currentCell,innerColumnField.field.get(obj),innerColumnField.colField.alignment(),innerColumnField);
                                if(innerColumnField.colField.width() == -1){
                                    dealColumnWidth(currentCell);
                                }
                            }


                            columnField.mapKeys.add(mapKey);
                        }

                    }
                }


            }
        }

        if(bgColorField != null){
            Object o = bgColorField.get(entity);
            if(bgColorField.getType() == int.class || bgColorField.getType() == Integer.class){
                int bgColorValue = (int) o;
                if(bgColorValue != 0){
                    if(mergeRowMaxNum > 0){
                        for(int i = 0; i < mergeRowMaxNum; i++){
                            deeperBgColorRegions.add(currentRowIndex + i);
                        }
                    }
                    else{
                        deeperBgColorRegions.add(currentRowIndex);
                    }

                }
            }
        }

        if(mergeRowMaxNum > 0){
            currentRowIndex += mergeRowMaxNum;
        }else{
            currentRowIndex ++;
        }

        return currentRowIndex;
    }

}
